import { ElMessage } from "element-plus";
import { defineStore } from "pinia";
import { computed, reactive, ref } from "vue";
import type { GroupMembersList, ChatFileInfo, PullGroupBasicInfo, MembersInfo, GroupMessage, PrivateMessage, StockPrivateMessage, StockFriendObject, StockGroupObject, StockGroupMessage } from "../types/types";
import type { PersistenceOptions } from "pinia-plugin-persistedstate";
import { userStore } from "./userStore";

interface ChatState {
    groupMessages: Record<string, GroupMessage[]>;      // key = groupId
    privateMessages: Record<string, PrivateMessage[]>;  // 新增：key = 好友 id
}

export const chatStore = defineStore('chatStore', () => {

    /* ========== 1. 群聊消息 ========== */
    const groupMessages = reactive<ChatState['groupMessages']>({});
    /** 向指定群追加一条消息（自动去重） */
    function addGroupMessage(msg: GroupMessage | GroupMessage[]) {
        // 分批处理对象信息和数组信息
        if (Array.isArray(msg)) {
            msg.forEach((singleMsg: GroupMessage) => {
                addGroupMessage(singleMsg);
            })
        } else {
            const list = groupMessages[msg.groupId] ??= [];
            if (!list.find(m => m.id === msg.id)) list.push(msg);
        }
    }
    /** 获取某群排序后的消息 */
    const getGroupMessages = computed(
        () => (groupId: string) =>
            (groupMessages[groupId] ?? [])
                .slice()
                .sort((a, b) => new Date(a.timeStamp).getTime() - new Date(b.timeStamp).getTime())
    );
    /**
     * @param groupId 群聊Id标志
     * @param clearType 清除类型，1、只清除聊天记录2、退出群聊时直接清除这个对象属性（直接修改数组了）
     */
    // 根据群聊Id清除本地缓存信息
    function clearGroupInfoByGroupId(groupId: string, clearType: string) {
        // 确保 groupId 是字符串类型
        if (typeof groupId !== 'string') {
            throw new Error('groupId must be a string');
        }
        switch (clearType) {
            case "clear-chat-message":
                if (groupMessages.hasOwnProperty(groupId)) {
                    groupMessages[groupId] = [];
                }
                break;
            case "quit-and-clear":
                // 退出群聊时直接清除这个对象属性
                delete groupMessages[groupId];
                break;
            default:
                // 如果 clearType 不是预期的值，可以抛出错误或执行默认行为
                console.warn(`Unknown clearType: ${clearType}. No action taken.`);
                break;
        }
    }

    /* ========== 2. 单聊消息 ========== */
    const privateMessages = reactive<ChatState["privateMessages"]>({});
    /** 追加单聊消息（自动去重）修改为双向可见 */
    function addPrivateMessage(raw: PrivateMessage | PrivateMessage[]) {
        if (raw === undefined) return;
        const me = userStore().userInfo.uu_id
        // 分开处理对象和数组
        if (Array.isArray(raw)) {
            raw.forEach((message: PrivateMessage) => {
                addPrivateMessage(message);
            })
        } else {
            const from = raw.from;
            const to = raw.to;

            // 1. 计算两个会话 id
            const chatId1: string = from === me ? to : from;   // 我 ↔ 对方
            const chatId2: string = from === me ? from : to;    // 对方 ↔ 我

            // 2. 写入两份（去重）
            [chatId1, chatId2].forEach(cid => {
                if (!privateMessages[cid]) {
                    privateMessages[cid] = reactive([]);
                }

                // 检查是否已经存在该消息
                const existingMessageIndex = privateMessages[cid].findIndex(m => m.id === raw.id);
                // 不存在则直接添加
                if (existingMessageIndex === -1) privateMessages[cid].push(raw);
            });
        }
    }
    /** 获取与某好友的排序后消息 */
    const getPrivateMessages = computed(
        () => (friendId: string) =>
            (privateMessages[friendId] || [])
                .slice()
                .sort((a, b) => +new Date(a.timeStamp) - +new Date(b.timeStamp))
    );

    /* ========== 3. 文件信息 ========== */
    let storageChatFileInfo = ref<ChatFileInfo[]>([])

    function setFileInfo(file: ChatFileInfo) {
        ElMessage.warning("触发store中存储数据的函数了！")
        // 检查是否存在相同的数据存在
        const existingIndex = storageChatFileInfo.value.findIndex((f: ChatFileInfo) => f.fileKey === file.fileKey);
        if (existingIndex !== -1) {
            // 如果存在相同的数据则进行更新
            storageChatFileInfo.value[existingIndex] = file;
        } else {
            // 如果不存在则添加数据
            storageChatFileInfo.value.push(file);
        }
    }



    // 存储群聊信息         是基本信息不是群聊聊天信息
    const storageChatGroupInfo = reactive<PullGroupBasicInfo[]>([]);
    /*
     * 返回值：void
     * @param group     可以接收一个PullGroupBasicInfo类型的参数，这个参数可以是对象也可以是一个数组
     * 函数功能：1、先进行数据包装（是数组直接使用反之包装成一个数组）2、都是一样的处理逻辑，判断groupId、group_id
    */
    function storageGroupInfo(group: PullGroupBasicInfo | PullGroupBasicInfo[]): void {
        // 如果传入的是数组，则逐个处理每个元素，如果传入的不是数组则包装成数组
        const groups = Array.isArray(group) ? group : [group];
        groups.forEach((groupItem: PullGroupBasicInfo): void => {

            // 查找是否存在相同的群组信息
            const existingItemIndex = storageChatGroupInfo.findIndex((item: PullGroupBasicInfo) => item.group_id === groupItem.group_id)

            if (existingItemIndex !== -1) {
                // 如果存在则更新存在的对象     在这里需要确保在动态添加数据时不会丢失vue3的响应式追踪
                storageChatGroupInfo.splice(existingItemIndex, 1, { ...storageChatGroupInfo[existingItemIndex], ...groupItem });
                // storageChatGroupInfo[existingItemIndex] = { ...storageChatGroupInfo[existingItemIndex], ...cleanedGroupItem };
            } else {
                // 如果不存在则直接push
                storageChatGroupInfo.push(groupItem);
            }

        })
    }
    // 主动退出时通过groupId删除对应的群聊信息
    function quitGroup(groupId: string) {
        // 先查找是否存在，确保数据的安全性
        const existingIndex = storageChatGroupInfo.findIndex((group: PullGroupBasicInfo) => group.group_id === groupId);
        if (existingIndex !== -1) {
            // 找到了对应的群聊信息，就在数组中删除
            storageChatGroupInfo.splice(existingIndex, 1);
        } else {
            ElMessage.error("未找到对应的群聊信息！");
            return;
        }
    }



    // 存储群成员at列表信息
    const storageGroupMembersList = reactive<GroupMembersList>({})
    // 对群成员消息处理的三个函数（保存、新增、删除）
    // 1、保存（覆盖）整个群成员列表
    function setGroupMembers(groupId: string, membersList: MembersInfo[]) {
        storageGroupMembersList[groupId] = membersList;
    }
    // 2、新增单个成员(后期优化，可以是单个、可以是多个（数组）)
    function addGroupMembers(groupId: string, member: MembersInfo | MembersInfo[]) {
        // 确保存储中存在该组的成员列表，如果不存在则初始化为空数组
        if (!storageGroupMembersList[groupId]) storageGroupMembersList[groupId] = [];
        // 将单个成员或成员数组统一为数组处理
        const membersToAdd = Array.isArray(member) ? member : [member];
        // 遍历要添加的成员数组
        membersToAdd.forEach((member: MembersInfo) => {
            // 检查是否存在相同key的成员
            if (!storageGroupMembersList[groupId].some(existingMember => existingMember.key === member.key)) {
                // 如果不存在，则添加到组成员列表中
                storageGroupMembersList[groupId].push(member);
            }
        })
    }
    // 删除群成员
    function removeMembers(groupId: string, memberId: string) {
        const list = storageGroupMembersList[groupId];
        if (!list) return;
        const index = list.findIndex((m) => m.key === memberId);
        if (index !== -1) list.splice(index, 1);
        console.log(storageGroupMembersList[groupId]);
    }
    // ------------- 新增开始 -------------
    /**
     * 当前群成员列表对应的 Map<label, MembersInfo>
     * 依赖 storageGroupMembersList，自动响应更新
     * 用法：const map = chatStore.membersMap(groupId)
     */
    const memberMap = computed(
        () => (groupId: string) => {
            const list = storageGroupMembersList[groupId] || [];
            return new Map<string, MembersInfo>(list.map(m => [m.label, m]))
        }
    );

    // 存储群聊信息--键值对方式存储数据
    const stockFriendMessage = reactive<StockFriendObject>({});
    const stockGroupMessage = reactive<StockGroupObject>({});
    function storeFriendMessage(friendId: string, message: StockPrivateMessage[]) {
        stockFriendMessage[friendId] = [];
        stockFriendMessage[friendId] = message;
    }
    function storeGroupMessage(groupId: string, message: StockGroupMessage[]) {
        stockGroupMessage[groupId] = [];
        stockGroupMessage[groupId] = message;
    }

    return {
        /* 群聊消息 */
        groupMessages, addGroupMessage, getGroupMessages, clearGroupInfoByGroupId,

        /* 单聊 */
        privateMessages, addPrivateMessage, getPrivateMessages,

        /* 文件信息 */
        storageChatFileInfo, setFileInfo,

        /* 群基础信息 */
        storageChatGroupInfo, storageGroupInfo, quitGroup,

        /* 群成员 */
        storageGroupMembersList, setGroupMembers, addGroupMembers, removeMembers,
        memberMap,

        /* 存储所有的聊天信息 */
        stockFriendMessage,
        storeFriendMessage, stockGroupMessage, storeGroupMessage
    }

}, {
    persist: {
        key: "chat_info",
        paths: ["storageGroupMembersList"],
        storage: localStorage
    } as PersistenceOptions
})